package com.fowo.api.syncAmazon.core.sync;

import com.amazon.spapi.model.reports.CreateReportSpecification;
import com.amazon.spapi.model.reports.Report;
import com.amazon.spapi.model.reports.ReportDocument;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.entity.TmpFbaInventory;
import com.fowo.api.entity.Warehouse;
import com.fowo.api.service.impl.ShopInfoServiceImpl;
import com.fowo.api.service.impl.TmpFbaInventoryServiceImpl;
import com.fowo.api.service.impl.WarehouseServiceImpl;
import com.fowo.api.syncAmazon.core.AbstractAmazonSyncData;
import com.fowo.api.syncAmazon.core.ReportApiType;
import com.fowo.api.syncAmazon.entity.ApiDefine;
import com.fowo.api.syncAmazon.entity.ApiRequestLog;
import com.fowo.api.syncAmazon.mapper.AmazonTmpMapper;
import com.fowo.api.syncAmazon.util.AmzDateUtils;
import com.fowo.api.syncAmazon.util.GeneralUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @fileName: FBAReservedInventorySync
 * @Description: 代码目的，作用，如何工作
 * @Author: yyf
 * @Date: 2024/2/26 0026 11:19
 */
@Component
public class FBAReservedInventorySync extends AbstractAmazonSyncData {
    @Resource
    private TmpFbaInventoryServiceImpl tmpFbaInventoryService;

    @Resource
    private ShopInfoServiceImpl shopInfoServiceImpl;

    @Resource
    private WarehouseServiceImpl warehouseService;

    @Resource
    private AmazonTmpMapper amazonTmpMapper;

    private ApiDefine apiDefine = ApiDefine.builder()
            .apiCode("FBA_reserved_inventory")
            .initdate(1)
            .timeInterval(1)
            .timeIntervalType("day").build();

    @Override
    protected ApiDefine setApiDefine() {
        return apiDefine;
    }


    @Override
    protected void requestData() throws Exception {
        // 获取卖家账号信息
        String platform = "Amazon";
        this.getAuthority(platform);
        // 查询该账号下所有店铺
        LambdaQueryWrapper<ShopInfo> shopInfosWrapper = new LambdaQueryWrapper<>();
        shopInfosWrapper.eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01");
        List<ShopInfo> shopInfoList = shopInfoServiceImpl.list(shopInfosWrapper);

        // 清空缓存表
        amazonTmpMapper.deleteFbaInventory();

        //请求报告
        for (ShopInfo shopInfo : shopInfoList) {
            //创建报告 -查询参数
            List<String> marketplaceIds = Arrays.asList(shopInfo.getMarketplaceId().split(","));
            CreateReportSpecification body = new CreateReportSpecification();
            body.setReportType(ReportApiType.GET_RESERVED_INVENTORY_DATA);
            body.setMarketplaceIds(marketplaceIds);
            // 获取拉取的时间区间
            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(startTime));
            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(endTime));

            // 第一步 创建报告
            final String reportId = retryCreateReport(shopInfo, body);
            // 第二步 检验报告是否完成
            Report report = retryCheckReport(shopInfo, reportId);
            // 第三步 获取报告连接
            ReportDocument reportDocument = getReportDocument(shopInfo,report.getReportDocumentId());
            System.out.println(reportDocument.getUrl());

            if (reportDocument != null) {
                String compressionAlgorithm = reportDocument.getCompressionAlgorithm() != null ? reportDocument.getCompressionAlgorithm().getValue() : null;
                BufferedReader reader = this.getAndUnzipReport(reportDocument.getUrl(), compressionAlgorithm);
                try {
                    download(reader, shopInfo);
                }catch (Exception ex){
                    apiRequestLog.setErrorMessage("缓存至临时表异常："+ex);
                    apiRequestLog.setStatus(ApiRequestLog.FAIL);
                    apiRequestLogService.getBaseMapper().updateById(apiRequestLog);
                }finally {
                    reader.close();
                }
            }
        }
    }

    @Override
    protected <T> void download(T param, ShopInfo shop) throws IOException, IllegalArgumentException {
        BufferedReader reader = null;
        if (param instanceof BufferedReader){
            try {
                reader = (BufferedReader)param;
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }

        int lineNumber = 0;
        String line;
        Map<String,Integer> titleList = new HashMap<String,Integer>();
        Warehouse warehouse = warehouseService.getOne(Wrappers.lambdaQuery(Warehouse.class).eq(Warehouse::getSid, shop.getId()));
        Long wid = null;
        if(null != warehouse){
            wid = warehouse.getId();
        }
        List<TmpFbaInventory> list = new ArrayList<>();

        while ((line = reader.readLine()) != null) {
            TmpFbaInventory tmp = new TmpFbaInventory();
            String[] info = line.split("\t");
            int length = info.length;

            if (lineNumber == 0) {
                for (int i = 0; i < length; i++) {
                    titleList.put(info[i],i);
                }
            } else {
                if(info.length < titleList.size()){
                    continue;
                }
                Map<String, Object> fields = this.getFieldsFromInfo(info, titleList);
                tmp.setCreateTime(new Date());

                tmp.setMsku(fields.get("sku").toString());
                tmp.setFnsku(fields.get("fnsku").toString());
                tmp.setAsin(fields.get("asin").toString());
                fields.get("product-name");
                fields.get("reserved_qty");
                Integer reserved_customerorders= GeneralUtil.getIntegerValue(info, titleList, "reserved_customerorders");
                Integer reserved_fc_transfers= GeneralUtil.getIntegerValue(info, titleList, "reserved_fc-transfers");
                Integer reserved_fc_processing= GeneralUtil.getIntegerValue(info, titleList, "reserved_fc-processing");
                tmp.setWarehouseToBeAdjusted(reserved_customerorders);
                tmp.setToBeShipped(reserved_fc_transfers);
                tmp.setDuringWarehouseAdjustment(reserved_fc_processing);
                tmp.setWarehouse(wid);
                tmp.setSid(shop.getId());
                list.add(tmp);
            }
            lineNumber++;
        }

        // 写入同步数据量
        Integer dataVolume = apiRequestLog.getDataVolume() == null ? 0 : apiRequestLog.getDataVolume();
        apiRequestLog.setDataVolume(dataVolume+list.size());
        tmpFbaInventoryService.saveBatch(list);

    }

    @Override
    protected void updateOrInsertData() {
        amazonTmpMapper.updateFbaInventoryReserved();

        // 完成本次同步日志
        apiDefine.setStatus(ApiDefine.SUCCESS);
        if(apiDefine.getLastDataTime() == null){
            apiDefine.setLastDataTime(endTime);
        } else if (endTime.after(apiDefine.getLastDataTime())) {
            apiDefine.setLastDataTime(endTime);
        }
        apiDefineService.getBaseMapper().updateById(apiDefine);
    }
}
